package model

import (
	"fmt"
	"gorm.io/gorm/clause"
)

type Item struct {
	Id string		`xml:"-" json:"id" gorm:"column:id;primary_key;not null;index"`
	Code string		`xml:"code,attr" json:"code"  gorm:"column:code;primary_key;not null;index"`			//item_code
	//Id string		`xml:"-" json:"id"`
	//Code string		`xml:"code,attr" json:"code"`			//item_code
	Key string		`xml:"key,attr" json:"key" `
	Tag string		`xml:"-" json:"tag" gorm:"index"`
	Name string		`xml:"name,attr" json:"name"`			//别名
	Type string		`xml:"type,attr" json:"type"`		//解析类型
	Convert *int		`xml:"convert,attr" json:"convert" gorm:"default:0"`			//转化类型  0x00:数值变换   y=ax+b     0x01:幅值变换   def:0x00
	Kfac float64	`xml:"kfac,attr" json:"kfac" gorm:"default:1"`			//比例系数,最小值	def:1
	Offs float64	`xml:"offs,attr" json:"offs" gorm:"default:0"`			//偏移值最大值,最大值	def:0
	Unit string		`xml:"unit,attr" json:"unit"`			//单位名称

	//Value interface{} `xml:"value,attr" json:"value"`
	//Quality bool `xml:"quality,attr" json:"quality"`

	Direction *int 	`xml:"direction,attr" json:"direction" gorm:"default:1" `				//方向 0x01读  0x10写 0x11读写			def: 0x01
	SaveType *int	`xml:"savetype,attr" json:"savetype" gorm:"column:savetype;default:2" `				// 0x00 不存储  0x01变化存储  0x10时间存储  0x11变化+时间	def: 0x00
	SavePeriodMin *int	`xml:"saveperiodmin,attr" json:"saveperiodmin" gorm:"column:saveperiodmin;default:100"`			//最小存储周期(ms)	def:0
	SavePeriodMax *int	`xml:"saveperiodmax,attr" json:"saveperiodmax" gorm:"column:saveperiodmax;default:10000"`			//最大存储周期(ms)	def:10000
	SaveDead float64		`xml:"savedead,attr" json:"savedead" gorm:"column:savedead;default:0" `			//变化死区	def: 0

	DecimalPoints *int	`xml:"decimalpoints,attr" json:"decimalpoints" gorm:"column:decimalpoints;default:-1" `			//小数点位数			def: -1	全部显示
	MinEU float64		`xml:"mineu,attr" json:"mineu" gorm:"column:mineu;default:-99999"`			//最小值		def: -99999
	MaxEU float64		`xml:"maxeu,attr" json:"maxeu" gorm:"column:maxeu;default:99999"`			//最大值		def: 99999

	//动态字段
	Ts int64		`xml:"-" json:"-" gorm:"-"`			//最新时间戳
	Value interface{} `xml:"-" json:"-" gorm:"-"`
	Quality bool `xml:"-" json:"-" gorm:"-"`
	Status int `xml:"-" json:"-" gorm:"-"`
}
func FindItems(filter *Item)[]Item{
	var items []Item
	if err:=sqldb.Find(&items,filter).Error;err != nil{
		fmt.Println(err)
		return nil
	}else{
		return items
	}
}
func DeleteItems()(int64,error){
	var items []Item
	sqldb.Find(&items)
	index :=0
	for i:=0; i < len(items); i++{
		if _,err := items[i].Delete();err != nil{
			return int64(index),err
		}
		index += 1
	}
	return int64(index),nil
}
func InsertItems(items []Item)error{
	length := len(items)
	m := length/10
	n := length%10

	if m >0{
		for i:=0; i < m; i++{
			it := make([]Item,10)
			copy(it,items[i*10:i*10+10])
			ret := sqldb.Create(&it)
			if ret.Error != nil{
				return ret.Error
			}
		}
	}
	if n > 0{
		it := make([]Item,n)
		copy(it,items[m*10:])
		ret := sqldb.Create(&it)
		if ret.Error != nil{
			return ret.Error
		}
	}
	return nil
	//if err:=sqldb.Create(&items).Error;err != nil{
	//	return err
	//}else{
	//	return nil
	//}
}
func(p* Item)Insert() error{
	var mods []Module
	sqldb.Find(&mods,&Module{Id:p.Id})
	if mods != nil && len(mods) > 0{
		if mods[0].Catagory == ""{
			p.Tag = mods[0].Name
		}else{
			p.Tag =  mods[0].Catagory + ":"  +mods[0].Name
		}
		return sqldb.Create(p).Error
	}else{
		return sqldb.Create(p).Error
	}
}
func (p* Item) Save()(int64,error){
	var mods []Module
	sqldb.Find(&mods,&Module{Id:p.Id})
	if mods != nil && len(mods) > 0{
		if mods[0].Catagory == ""{
			p.Tag = mods[0].Name
		}else{
			p.Tag =  mods[0].Catagory + ":"  +mods[0].Name
		}
	}
	ret := sqldb.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "id"},{Name:"code"}},
		DoUpdates: clause.AssignmentColumns([]string{"key", "tag", "name", "type", "convert", "kfac","offs","unit","direction","savetype","saveperiodmin","saveperiodmax","savedead","decimalpoints","mineu","maxeu"}),
	}).Updates(p)
	return ret.RowsAffected,ret.Error
}
func (p* Item) Delete()(int64,error){
	db :=sqldb.Where(&Item{Id:p.Id,Code:p.Code}).Delete(&Item{})
	return db.RowsAffected,db.Error
}
